package com.itlin.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itlin.bean.Category;
import com.itlin.bean.Dish;
import com.itlin.bean.DishFlavor;
import com.itlin.bean.PageParam;
import com.itlin.common.CustomException;
import com.itlin.dao.DishDao;
import com.itlin.dto.DishDto;
import com.itlin.service.CategoryService;
import com.itlin.service.DishFlavorService;
import com.itlin.service.DishService;
import com.itlin.service.SetmealDishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 所谓伊人
 * @date 2022/3/24 - 20:13
 */
@Slf4j
@Transactional
@Service
public class DishServiceImpl implements DishService {

    @Autowired
    private DishDao dao;

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private SetmealDishService setmealDishService;

    @Override
    public int countByCid(long cid) {

        LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();

        qw.eq(Dish::getCategoryId,cid);

        return dao.selectCount(qw);
    }

    @Override
    public int add(DishDto dishDto) {

        // Dish(id=null, name=馕坑肉)
        // log.info(String.valueOf(dishDto));

        //此时disDto的id为null,但是完成插入操作后,MP会自动返还disDto的id到dishDto;
        int row = dao.insert(dishDto);

        // Dish(id=1507268763572879361, name=馕坑肉)
        // log.info(String.valueOf(dishDto));

        if (row > 0 && !dishDto.getFlavors().isEmpty()) {

            int row2 = 0;

            for (DishFlavor flavor:dishDto.getFlavors()) {

                flavor.setDishId(dishDto.getId());

                row2 += dishFlavorService.add(flavor);

            }

            return row2 == dishDto.getFlavors().size() ? 1 : 0;
        }

        return row;
    }

    @Override
    public IPage<DishDto> findPage(PageParam pageParam) {

        LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();

        qw.like(pageParam.getName() != null, Dish::getName, pageParam.getName());

        IPage<Dish> page = new Page<>(pageParam.getPage(), pageParam.getPageSize());

        IPage<Dish> dishIPage = dao.selectPage(page, qw);

        // Dish表格中只有分类的id，没有分类的名字，所以我们获得分类id后还要去分类表里面查询分类的名字，在包装到DTO里面返还给前端

        List<Dish> records = dishIPage.getRecords();

        List<DishDto> dishDtos = new ArrayList<>();

        for (Dish dish : records) {

            Category category = categoryService.findById(dish.getCategoryId());

            DishDto dishDto = new DishDto();

            // 可以把一个对象的属性的值复制到另一个对象，前提是两个对象有相同的属性
            BeanUtils.copyProperties(dish, dishDto);

            dishDto.setCategoryName(category.getName());

            //为了修改菜品时方便，我们返回前端数据时要将口味也返回。口味要通过菜品id去口味表查询
            List<DishFlavor> dishFlavors = dishFlavorService.findByDishId(dishDto.getId());
            dishDto.setFlavors(dishFlavors);

            dishDtos.add(dishDto);
        }

        IPage<DishDto> dishDtoPage = new Page<>();

        dishDtoPage.setTotal(dishIPage.getTotal());
        dishDtoPage.setRecords(dishDtos);

        return dishDtoPage;
    }

    @Override
    public int update(DishDto dishDto) {

        int row = dao.updateById(dishDto);

        dishFlavorService.deleteByDishId(dishDto.getId());

        List<DishFlavor> flavors = dishDto.getFlavors();

        if (row > 0 && !flavors.isEmpty()) {

            int row2 = 0;

            for (DishFlavor flavor:dishDto.getFlavors()) {

                flavor.setDishId(dishDto.getId());

                row2 += dishFlavorService.add(flavor);

            }

            return row2 == dishDto.getFlavors().size() ? 1 : 0;
        }
        return row;
    }

    @Override
    public List<DishDto> findByCategoryId(long categoryId, Integer status) {
        LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();

        qw.eq(Dish::getCategoryId, categoryId);

        qw.eq(status != null, Dish::getStatus, status);


        List<Dish> dishList = dao.selectList(qw);

        //4. 要求还要去查询口味表
        return dishList.stream().map(dish -> {

            //4.1 拿着菜品的id去查询口味表，得到这个菜品的口味数据
            List<DishFlavor> flavorList = dishFlavorService.findByDishId(dish.getId());

            //4.2 遍历一次，构建一个DishDto对象
            DishDto dto = new DishDto();

            //4.3 把 dish的数据拷贝到DishDto身上
            BeanUtils.copyProperties(dish , dto);

            //4.4 把查询到的口味数据，也一并设置进来
            dto.setFlavors(flavorList);

            //4.5 返回一个新的对象。
            return dto;
        }).collect(Collectors.toList());
    }

    @Override
    public int updateStatus(Dish dish,List<Long> ids){
        LambdaQueryWrapper<Dish> lq=new LambdaQueryWrapper<>();
        lq.in(Dish::getId,ids);
        int row = dao.update(dish, lq);
        return row;
    };

    @Override
    public int deleteById(List<Long> ids){
//        查询是否有启售菜品
        LambdaQueryWrapper<Dish> lq=new LambdaQueryWrapper<>();
        lq.in(Dish::getId,ids).eq(Dish::getStatus,1);
        int counts = dao.selectCount(lq);
//        如果有，则直接返回0，不再删除；
        if (counts>0){
            return 999999999;
//        如果没有则删除菜品数据
        }else {
            LambdaQueryWrapper<Dish> lq2=new LambdaQueryWrapper();
            lq2.in(Dish::getId,ids);
            int row = dao.delete(lq2);
//        删除成功后删除口味数据
            if (row==ids.size()){
                for (Long id:ids) {
                dishFlavorService.deleteByDishId(id);
                }
//                删除套餐内菜品数据
                setmealDishService.deleteByDishId(ids);
                return row;
            }else {
                throw new CustomException("未知原因，删除失败");
            }
        }
    }
}
